package com.deadlock8;
// 解释
class A {
    public synchronized void foo(B b) {
        // 输出当前线程名和进入A实例的foo方法的信息
        System.out.println("当前线程名：" + Thread.currentThread().getName()
                + "进入了A实例的foo方法");
        try {
            // 让当前线程休眠200毫秒
            Thread.sleep(200);
        } catch (InterruptedException e) {
            // 如果发生中断异常，抛出运行时异常
            throw new RuntimeException(e);
        }
        // 输出当前线程名和企图调用B实例的last方法的信息
        System.out.println("当前线程名：" + Thread.currentThread().getName()
                + "企图调用B实例的last方法");
        b.last();
    }

    public synchronized void last() {
        // 输出进入A类的last内部的信息
        System.out.println("进入了A类的last内部");
    }
}

class B {
    public synchronized void bar(A a) {
        // 输出当前线程名和进入B实例的bar方法的信息
        System.out.println("当前线程名：" + Thread.currentThread().getName()
                + "进入了B实例的bar方法");
        try {
            // 让当前线程休眠200毫秒
            Thread.sleep(200);
        } catch (InterruptedException e) {
            // 如果发生中断异常，抛出运行时异常
            throw new RuntimeException(e);
        }
        // 输出当前线程名和企图调用A实例的last方法的信息
        System.out.println("当前线程名：" + Thread.currentThread().getName()
                + "企图调用A实例的last方法");
        a.last();
    }

    public synchronized void last() {
        // 输出进入B类的last内部的信息
        System.out.println("进入了B类的last内部");
    }
}
// 实现Runnable接口的类，用于模拟死锁情况
public class DeadLock2 implements Runnable {
    // 实例化对象
    A a = new A();
    B b = new B();

    // 初始化方法，先调用a对象的foo方法，再调用b对象的bar方法
    public void init(){
        // 设置当前线程名为"进入主线程之后"
        Thread.currentThread().setName("进入主线程之后");
        // 调用a对象的foo方法，传入b对象作为参数
        a.foo(b);
        // 输出进入主线程之后的信息
        System.out.println("进入主线程之后");
    }
    @Override
    public void run() {
        // 设置当前线程名为"副线程"
        Thread.currentThread().setName("副线程");
        // 调用b对象的bar方法，传入a对象作为参数
        b.bar(a);
        // 输出进入副线程之后的信息
        System.out.println("进入副线程之后");
    }

    public static void main(String[] args) {
        // 创建DeadLock2对象
        DeadLock2 dl = new DeadLock2();
        // 创建新线程并启动，传入dl对象作为参数
        new Thread(dl).start();
        // 调用init方法，模拟死锁情况
        dl.init();
    }
}
